由於 HTTP 是無狀態的通訊協定,如果沒有額外處理,每次請求都會是獨立的,沒辦法保留來自客戶端的資料。今天會介紹要怎麼在應用程式中儲存或暫存資料跟狀態。
開發人員可以由幾個面向來判斷需要使用哪種狀態管理的方式:
ASP.NET Core 框架中好幾種方式來管理狀態,包括:
Cookie
以類似 key-value 的資料結構儲存在客戶端,會隨著每次請求被傳送到伺服器端,所以當 Cookie
數量增加或儲存的值長度較大的時候,請求的封包會隨之變大。由於在客戶端可以新增、修改或刪除 Cookie
,不建議將敏感資料以這個方式儲存,或者要加密後再儲存。在 Controller
中以下列程式來讀寫 Cookie
:
public class ApplicationStatesController : Controller
{
public IActionResult Cookie()
{
Request.Cookies.TryGetValue("SampleCookie", out var cookieValue);
// 把取出的值寫進 log
_logger.LogDebug(cookieValue);
Response.Cookies.Append("SampleCookie", Guid.NewGuid().ToString(), new CookieOptions
{
MaxAge = TimeSpan.FromMinutes(30)
});
return new EmptyResult();
}
}
Response.Cookies.Append
的第三個參數是可選的 CookieOptions
類別,用來設定相關參數。範例中是將 SampleCookie
的值設定為 30 分鐘後過期。執行後可以在瀏覽器的開發工具中看到當前網域的所有 cookie。
在其他地方可能會翻譯成「工作階段」。Session
是將資料存在伺服器的記憶體或資料庫中,再把一個唯一識別值 (id) 寫到 Cookie 中,並透過此 id 來存取資料。
要使用 Session
的設定比 Cookie 麻煩很多,需要在 Startup.cs
中設定:
Session
儲存區的 IDistributedCache
。目前提供記憶體、資料庫和 Redis 三種儲存方式。Startup.ConfigureServices
中呼叫 AddSession
。Startup.Configure
中呼叫 UseSession
。public class Startup
{
public void ConfigureServices(IServiceCollection services){
// ...other services configurations
services.AddDistributedMemoryCache();
services.AddSession();
}
public void Configure(IApplicationBuilder app)
{
// ...other middlewares registrations
app.UseSession();
// ...other middlewares registrations
}
}
需要特別注意加入中介層的順序,如果在 UseSession
之前先呼叫 UseMvc
,就沒辦法在 MVC 架構中的程式使用 Session
。設定完成後就可在應用程式中用 SessionExtensions
提供的各種方法來讀寫 Session
值。由於 Session
儲存在 IDistributedCache
中,資料都需要轉換成 byte[]
,只有另外提供 string
和 int32
的介面做讀寫。如果要儲存物件,就需要序列化成字串來處理。官方文件中有提供序列化的擴充方法可以參考:
public static class SessionSerializerExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
}
在程式中讀寫的方式:
public IActionResult Session()
{
var sessionValue = HttpContext.Session.GetString("SampleSession");
HttpContext.Session.SetInt32("Year", 2018);
HttpContext.Session.Set("CurrentDate", DateTime.Now);
return new EmptyResult();
}
今天就先講到這吧~明天再來談談其他儲存狀態的方式